package com.arcaneshift.servlet.action.game;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.arcaneshift.model.action.game.BattleEngine;
import com.arcaneshift.model.action.game.BattlePlayer;
import com.arcaneshift.model.request.GetStartGameStatsRequest;
import com.arcaneshift.model.response.GetStartGameStatsResponse;
import com.arcaneshift.model.validators.GameValidator;
import com.arcaneshift.servlet.util.network.RequestAction;
import com.arcaneshift.servlet.util.parser.GetStartGameStatsXMLParser;
import com.arcaneshift.util.GameCacheContainer;
import com.common.model.abstracts.AbstractRequest;
import com.common.model.abstracts.AbstractValidator;
import com.common.model.validators.ActionValidator;
import com.common.security.abstracts.AbstractException;
import com.common.security.errors.ParserError;
import com.common.security.exceptions.ParserException;
import com.common.servlet.abstracts.AbstractParserServlet;
import com.common.servlet.interfaces.IParser;
import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;

public class GetStartGameStatsServlet extends AbstractParserServlet {
	private static final long serialVersionUID = 1L;
	private static Set<AbstractValidator> validators = new HashSet<AbstractValidator>();
	
	private GetStartGameStatsRequest requestContent;
	private GetStartGameStatsXMLParser parser = new GetStartGameStatsXMLParser();
	
	static {
		validators.add(new ActionValidator(RequestAction.GET_START_GAME_STATS));
		validators.add(new GameValidator());
	}
	
	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response) {
		try {
			GetStartGameStatsResponse gameStatsResponse = new GetStartGameStatsResponse();
			
			String gameId = requestContent.getGameId();
			BattleEngine game = GameCacheContainer.getGame(gameId);
			List<BattlePlayer> battlePlayers = game.getBattlePlayers();

			gameStatsResponse.setRequestAction(requestContent.getAction());
			gameStatsResponse.setArena(game.getArena());
			gameStatsResponse.setTerran(game.getTerran());
			gameStatsResponse.setBattlePlayers(battlePlayers);
			
			//Logger.getAnonymousLogger().severe(parser().parseResponse(gameStatsResponse));
			
			for (BattlePlayer battlePlayer : battlePlayers) {
				Logger.getAnonymousLogger().severe("Player: " + requestContent.getPlayer() + " - " + battlePlayer.getPlayerNumber() + " Channel: " + battlePlayer.getPlayer().getChannel());
				if (requestContent.getPlayer() == battlePlayer.getPlayerNumber() && battlePlayer.getPlayer().getChannel() != null) {
					sendChannelResponse(battlePlayer.getPlayer().getSession().getUserId(), gameStatsResponse);
					response.getWriter().close();
					return;
				}
			}
			Logger.getAnonymousLogger().severe("No channel");
			
			response.setContentType("text/xml");
			response.getWriter().write(parser().parseResponse(gameStatsResponse));
			response.getWriter().close();
		} catch (ParserException parserException) {
			exception(parserException, response);
		} catch (IOException ioException) {
			error(new ParserError(ParserError.STREAM_ERROR), response);
		}
	}

	private void sendChannelResponse(Long token, GetStartGameStatsResponse response) throws ParserException {
		ChannelService service = ChannelServiceFactory.getChannelService();
		service.sendMessage(new ChannelMessage(token.toString(), parser().parseResponse(response)));
		Logger.getAnonymousLogger().severe(token.toString());
	}
	
	@Override
	public void setRequest(AbstractRequest abstractRequest) {
		requestContent = (GetStartGameStatsRequest) abstractRequest;
	}

	@Override
	public Set<AbstractValidator> getValidators() {
		return validators;
	}

	@Override
	public IParser parser() {
		return parser;
	}

	@Override
	public void exception(AbstractException exception, HttpServletResponse response) {
		super.exception(exception, response);
		
		switch (exception.getCode()) {
			 case ParserException.RESPONSE_BAD_FORMAT: {
				 error(new ParserError(ParserError.RESPONSE_BAD_FORMAT), response);
				 break;
			 }
			 case ParserException.CONVERSION_EXCEPTION: {
				 error(new ParserError(ParserError.VALUE_CONVERT_ERROR), response);
				 break;
			 }
		}
	}
}
